﻿using System;
using System.Collections.Generic;
using System.Linq;
using Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using OpenAuth.App.Interface;
using OpenAuth.App.Request;
using OpenAuth.App.Response;
using OpenAuth.Repository.Domain;
using OpenAuth.Repository.Interface;


namespace OpenAuth.App
{
    public class MobileInspectApp : BaseApp<InspectPlan>
    {
        private RevelanceManagerApp _revelanceApp;
        private IAuth _auth;
        private ILogger<MobileInspectApp> _logger;

        /// <summary>
        /// 获取当前登入用户巡检数据
        /// </summary>
        /// <returns></returns>
        public MobileInspectInfo GetData()
        {
            var loginContext = _auth.GetCurrentUser();
            if (loginContext == null)
            {
                throw new CommonException("登录已过期", Define.INVALID_TOKEN);
            }

            //获取接下去2天可巡检的日程
            var now = DateTime.Now;
            var lastDay = now.AddDays(2);
            List<InspectSchedule> scheduleList;
            if (string.IsNullOrEmpty(loginContext.User.InspectTeam))
            {
                scheduleList = UnitWork.Find<InspectSchedule>(u => (u.StartTime > now &&
                u.EndTime < lastDay || u.StartTime < now && u.EndTime > now)
                && u.IsInspection == false && (u.Executor.Contains(loginContext.User.Id))).ToList();
            }
            else
            {
                scheduleList = UnitWork.Find<InspectSchedule>(u => (u.StartTime > now &&
                u.EndTime < lastDay || u.StartTime < now && u.EndTime > now)
                && u.IsInspection == false && (u.Executor.Contains(loginContext.User.Id) || u.ShiftTeam == loginContext.User.InspectTeam)).ToList();
            }

            if (scheduleList.Count == 0)
            {
                return new MobileInspectInfo();
            }
            foreach (var item in scheduleList)
            {
                item.Executor = loginContext.User.Id;
            }

            List<string> scheduleIdList = scheduleList.Select(p => p.InspectPlanId).ToList();
            if (scheduleIdList.Count == 0)
                return new MobileInspectInfo();
            var planList = UnitWork.Find<InspectPlan>(u => scheduleIdList.Contains(u.Id)).ToList();
            var planIdList = planList.Select(p => p.Id).ToList();
            var planContentList = UnitWork.Find<InspectPlanContent>(u => planIdList.Contains(u.InspectPlanId)).ToList();
            var areaIdList = planContentList.Select(p => p.InspectAreaId).ToList();
            var equipIdList = planContentList.Select(p => p.EquipmentInventoryId).ToList();
            var standardIdList = planContentList.Select(p => p.InspectStandardId).ToList();
            var areaList = UnitWork.Find<InspectArea>(u => areaIdList.Contains(u.Id)).ToList();
            var standardList = UnitWork.Find<InspectStandard>(u => standardIdList.Contains(u.Id)).ToList();
            var itemIdList = standardList.Select(p => p.Id).ToList();
            var standardItemList = UnitWork.Find<InspectStandardItems>(u => itemIdList.Contains(u.InspectStandardId)).ToList();
            var equipmentList = UnitWork.Find<EquipmentInventory>(u => equipIdList.Contains(u.Id)).ToList();
            MobileInspectInfo inspectList = new MobileInspectInfo()
            {
                Plans = planList,
                Areas = areaList,
                EquipmentInventories = equipmentList,
                PlanContents = planContentList,
                Standards = standardList,
                StandardItems = standardItemList,
                Schedules = scheduleList
            };
            return inspectList;
        }

        /// <summary>
        /// 上传巡检记录数据
        /// </summary>
        /// <param name="obj"></param>
        public void UploadRecord(InspectRecord obj)
        {
            //UnitWork.Update<InspectSchedule>(u => u.Id == obj.InspectScheduleId,
            //    u => new InspectSchedule { IsInspection = true });
            _logger.LogInformation("上传的巡检json:" + obj.ToJson());
            InspectSchedule schedule = null;
            //校验日程id是否正确
            var nowSchedule = UnitWork.Find<InspectSchedule>(u => u.Id == obj.InspectScheduleId);

            if (!nowSchedule.Any() && obj.ClassEndTime != null && obj.ClassStartTime != null)
            {
                schedule = UnitWork.Find<InspectSchedule>(u => u.InspectPlanId == obj.InspectPlanId
                    && u.StartTime == obj.ClassStartTime && u.EndTime == obj.ClassEndTime).FirstOrDefault();
                obj.InspectScheduleId = schedule.Id;
                _logger.LogInformation($"出现日程不匹配作业：计划id[{obj.InspectPlanId}],日程[{obj.ClassStartTime}-{obj.ClassEndTime}],newClassId[{schedule.Id}]");
            }
            else
            {
                schedule = nowSchedule.FirstOrDefault();
            }
            var record = UnitWork.Find<InspectRecord>(u => u.InspectScheduleId == obj.InspectScheduleId)
                .FirstOrDefault();
            if (record != null)
                return;
            if (obj.InspectRecordItems.Count > 0)
            {
                foreach (var item in obj.InspectRecordItems)
                {
                    if (item.EndTime.HasValue && item.EndTime.Value > schedule.EndTime)
                        item.IsOverTime = true;
                }
            }
            UnitWork.Add(obj);
            schedule.IsInspection = true;
            UnitWork.Update(schedule);
            //校验是否延迟上传
            if (obj.EndTime > schedule.EndTime)
            {
                UnitWork.Add(new InspectViolation
                {
                    InspectPlanId = obj.InspectPlanId,
                    OrgId = obj.OrgId,
                    InspectScheduleId = obj.InspectScheduleId,
                    Reason = "点检超时",
                    Category = 1,
                    IsViolation = true,
                    Status = 0
                });
                UnitWork.Delete<InspectViolation>(u => u.InspectScheduleId == obj.InspectScheduleId && u.Category == 0);
            }
            //校验是否点位漏检
            List<string> lackAreaIdList = new List<string>();
            var planContentCount = UnitWork.Find<InspectPlanContent>(u => u.InspectPlanId == obj.InspectPlanId).ToList();
            var currentAreas = obj.InspectRecordItems.Select(u => u.InspectAreaId);
            foreach (var inspectPlanContent in planContentCount)
            {
                if (!currentAreas.Contains(inspectPlanContent.InspectAreaId))
                {
                    lackAreaIdList.Add(inspectPlanContent.InspectAreaId);
                }
            }

            if (lackAreaIdList.Count > 0)
            {
                var areaList = UnitWork.Find<InspectArea>(u => lackAreaIdList.Contains(u.Id)).Select(u => u.Name)
                    .ToList();
                UnitWork.Add(new InspectViolation
                {
                    InspectPlanId = obj.InspectPlanId,
                    OrgId = obj.OrgId,
                    InspectScheduleId = obj.InspectScheduleId,
                    Reason = "点位漏检",
                    Category = 2,
                    IsViolation = true,
                    Status = 0,
                    LeakNum = lackAreaIdList.Count,
                    LeakArea = string.Join(",",areaList)
                });
            }
            UnitWork.Save();
        }

        public List<InspectPlan> GetAllPlans()
        {
            var plans = UnitWork.Find<InspectPlan>(u => true).Select(p => new InspectPlan() { Name = p.Name, Id = p.Id });
            return plans.ToList();
        }

        public List<EquipmentInventory> GetEquipmentInventories()
        {
            return UnitWork.Find<EquipmentInventory>(null)
                .Select(p => new EquipmentInventory { Id = p.Id, Name = p.Name, OrgId = p.OrgId }).ToList();
        }

        public List<Org> GetOrgList()
        {
            var loginContext = _auth.GetCurrentUser();
            if (loginContext == null)
            {
                throw new CommonException("登录已过期", Define.INVALID_TOKEN);
            }

            return loginContext.Orgs;
        }

        public List<InspectRecord> GetInspectRecords(QueryInspectRecordListReq req)
        {
            var loginContext = _auth.GetCurrentUser();
            if (loginContext == null)
            {
                throw new CommonException("登录已过期", Define.INVALID_TOKEN);
            }


            List<string> orgIdList = new List<string>();
            if (!string.IsNullOrEmpty(req.orgId))
            {
                var org = loginContext.Orgs.SingleOrDefault(u => u.Id == req.orgId);
                foreach (Org item in loginContext.Orgs)
                {
                    if (item.CascadeId.Contains(org.CascadeId))
                    {
                        orgIdList.Add(item.Id);
                    }
                }
            }
            else
            {
                orgIdList = loginContext.Orgs.Select(u => u.Id).ToList();
            }


            var objs = UnitWork.Find<InspectRecord>(u => orgIdList.Contains(u.OrgId));
            if (!string.IsNullOrEmpty(req.planId))
            {
                objs = objs.Where(u => u.InspectPlanId == req.planId);
            }
            if (!string.IsNullOrEmpty(req.startDate) && !string.IsNullOrEmpty(req.endDate))
            {
                DateTime startTime = Convert.ToDateTime(req.startDate);
                DateTime endTime = Convert.ToDateTime(req.endDate).AddDays(1).AddSeconds(-1);
                objs = objs.Where(u => u.StartTime > startTime && u.EndTime < endTime);
            }

            var result = objs.OrderByDescending(u => u.UploadTime)
                .Include(u => u.InspectPlan)
                .Include(u => u.InspectSchedule)
                .Include(u => u.User)
                .Skip((req.page - 1) * req.limit)
                .Take(req.limit).ToList();
            return result;
        }


        public List<DefectInventory> GetDefects(QueryDefectInventoryListReq req)
        {
            var loginContext = _auth.GetCurrentUser();
            if (loginContext == null)
            {
                throw new CommonException("登录已过期", Define.INVALID_TOKEN);
            }

            List<string> orgIdList = new List<string>();
            if (!string.IsNullOrEmpty(req.OrgId))
            {
                var org = loginContext.Orgs.SingleOrDefault(u => u.Id == req.OrgId);
                foreach (Org item in loginContext.Orgs)
                {
                    if (item.CascadeId.Contains(org.CascadeId))
                    {
                        orgIdList.Add(item.Id);
                    }
                }
            }
            else
            {
                orgIdList = loginContext.Orgs.Select(u => u.Id).ToList();
            }


            var objs = UnitWork.Find<DefectInventory>(u => orgIdList.Contains(u.OrgId));
            if (!string.IsNullOrEmpty(req.Code))
            {
                objs = objs.Where(u => u.Code.Contains(req.Code));
            }

            var result = objs.OrderByDescending(u => u.FindTime)
                .Include(u => u.EquipmentInventory)
                .Include(u => u.Org)
                .Include(u => u.User)
                .Skip((req.page - 1) * req.limit)
                .Take(req.limit).ToList();
            return result;
        }

        public MobileInspectApp(IUnitWork unitWork, IRepository<InspectPlan> repository,
            RevelanceManagerApp app, IAuth auth, ILogger<MobileInspectApp> logger) : base(unitWork, repository)
        {
            _revelanceApp = app;
            _auth = auth;
            _logger = logger;
        }
    }
}